#include "base_server.hpp"


void BaseServer::Listener::on_data_available(eprosima::fastdds::dds::DataReader* reader)
{
    CommonData request;
    eprosima::fastdds::dds::SampleInfo sample_info;

    reader->take_next_sample(&request, &sample_info);

    if (eprosima::fastdds::dds::InstanceStateKind::ALIVE_INSTANCE_STATE == sample_info.instance_state)
    {
        CommonData reply;

        auto now = std::chrono::system_clock::now();
        auto now_time = std::chrono::system_clock::to_time_t(now);
        auto local_time = std::localtime(&now_time);
        std::ostringstream oss;
        oss << "Response Time is ";
        oss << std::put_time(local_time, "%Y-%m-%d %H:%M:%S");
        auto time_str = oss.str();
        reply.data(time_str);

        eprosima::fastrtps::rtps::WriteParams write_params;
        write_params.related_sample_identity().writer_guid(sample_info.sample_identity.writer_guid());
        write_params.related_sample_identity().sequence_number(sample_info.sample_identity.sequence_number());
        this->_writer->write(reinterpret_cast<void*>(&reply), write_params);
    }
}

bool BaseServer::init()
{
        participant_ = eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->create_participant(0,
                        eprosima::fastdds::dds::PARTICIPANT_QOS_DEFAULT);

        if (nullptr == participant_)
        {
            return false;
        }

        request_type_ = eprosima::fastdds::dds::TypeSupport(new CommonDataPubSubType());
        reply_type_ = eprosima::fastdds::dds::TypeSupport(new CommonDataPubSubType());

        participant_->register_type(request_type_);
        participant_->register_type(reply_type_);

        publisher_ = participant_->create_publisher(eprosima::fastdds::dds::PUBLISHER_QOS_DEFAULT);

        if (nullptr == publisher_)
        {
            return false;
        }

        subscriber_ = participant_->create_subscriber(eprosima::fastdds::dds::SUBSCRIBER_QOS_DEFAULT);

        if (nullptr == subscriber_)
        {
            return false;
        }

        request_topic_ = participant_->create_topic("simple_service/request",
                        request_type_.get_type_name(), eprosima::fastdds::dds::TOPIC_QOS_DEFAULT);

        if (nullptr == request_topic_)
        {
            return false;
        }

        reply_topic_ = participant_->create_topic("simple_service/response",
                        reply_type_.get_type_name(), eprosima::fastdds::dds::TOPIC_QOS_DEFAULT);

        if (nullptr == reply_topic_)
        {
            return false;
        }

        eprosima::fastdds::dds::DataWriterQos writer_qos;
        writer_qos.history().kind = eprosima::fastdds::dds::KEEP_ALL_HISTORY_QOS;
        reply_writer_ = publisher_->create_datawriter(reply_topic_, writer_qos);

        if (nullptr == reply_writer_)
        {
            return false;
        }

        listener_ = { reply_writer_};

        eprosima::fastdds::dds::DataReaderQos reader_qos;
        reader_qos.reliability().kind = eprosima::fastdds::dds::RELIABLE_RELIABILITY_QOS;
        reader_qos.durability().kind = eprosima::fastdds::dds::TRANSIENT_LOCAL_DURABILITY_QOS;
        reader_qos.history().kind = eprosima::fastdds::dds::KEEP_ALL_HISTORY_QOS;
        request_reader_ = subscriber_->create_datareader(request_topic_, reader_qos, &listener_);

        if (nullptr == request_reader_)
        {
            return false;
        }

        return true;
}

void BaseServer::deinit()
{
    if (this->participant_ != nullptr) {
        this->participant_->delete_contained_entities();
        eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->delete_participant(this->participant_);
    }
}

